package com.abing.starry.strategy.login;

import cn.hutool.core.lang.Validator;
import com.abing.starry.common.ErrorCode;
import com.abing.starry.exception.BusinessException;
import com.abing.starry.exception.ThrowUtils;
import com.abing.starry.model.entity.UserEntity;
import com.abing.starry.model.enums.UserRoleEnum;
import com.abing.starry.model.request.user.UserLoginRequest;
import com.abing.starry.service.UserService;
import com.abing.starry.util.EncryptUtils;
import com.abing.starry.util.TokenUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.Objects;

import static com.abing.starry.constant.UserConstant.USER_LOGIN_STATE;
import static com.abing.starry.constant.UserConstant.USER_MAIL_CAPTCHA;

/**
 * @Author CaptainBing
 * @Date 2024/8/28 9:36
 * @Description 邮箱密码登录
 */
@LoginTypeConfig(loginType = LoginTypeEnum.CAPTCHA)
@RequiredArgsConstructor
public class CaptchaLoginStrategy implements LoginStrategy {


    private final StringRedisTemplate stringRedisTemplate;

    private final UserService userService;

    @Override
    public String doLogin(UserLoginRequest userLoginRequest) {
        String userAccount = userLoginRequest.getUserAccount();
        String captcha = userLoginRequest.getCaptcha();

        if (StringUtils.isAnyEmpty(userAccount, captcha)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        ThrowUtils.throwIf(!Validator.isEmail(userAccount), ErrorCode.PARAMS_ERROR, "邮箱格式不合法");

        String userMailCaptchaKey = USER_MAIL_CAPTCHA + userAccount;
        String cacheCaptcha = stringRedisTemplate.opsForValue().get(userMailCaptchaKey);
        ThrowUtils.throwIf(StringUtils.isEmpty(cacheCaptcha),ErrorCode.NOT_FOUND_ERROR,"验证码已失效");
        if (!StringUtils.equalsIgnoreCase(captcha,cacheCaptcha)){
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"验证码错误");
        }
        UserEntity currentUser = userService.getOne(Wrappers.lambdaQuery(UserEntity.class)
                                                     .eq(UserEntity::getUserAccount, userAccount));
        // 用户存在直接登录成功 否则注册用户
        if (!Objects.isNull(currentUser)){
            String token = TokenUtils.genToken(currentUser);
            stringRedisTemplate.opsForValue().set(USER_LOGIN_STATE + currentUser.getId(), token);
            return token;
        }
        synchronized (userAccount.intern()){
            UserEntity registerUser = new UserEntity();
            registerUser.setUserAccount(userAccount);
            registerUser.setUserName(userAccount);
            registerUser.setUserRole(UserRoleEnum.USER.getValue());

            String defaultPassword = cacheCaptcha;
            registerUser.setUserPassword(EncryptUtils.genUserPassword(defaultPassword));
            registerUser.setAccessKey(EncryptUtils.genApiKey());
            registerUser.setSecretKey(EncryptUtils.genApiKey());
            boolean saveUser = userService.save(registerUser);
            ThrowUtils.throwIf(!saveUser,ErrorCode.OPERATION_ERROR,"用户注册失败");
            String token = TokenUtils.genToken(registerUser);
            // token 存入缓存中 USER_LOGIN_STATE:id
            stringRedisTemplate.opsForValue().set(USER_LOGIN_STATE + registerUser.getId(), token);
            return token;
        }
    }
}
